package com.pdg.android.splorr.data;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.pdg.android.splorr.data.baseclasses.DataClientWithItems;
import com.pdg.android.splorr.data.enums.RoomDirection;
import com.pdg.android.splorr.data.enums.RoomState;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class Room extends DataClientWithItems<Maze,RoomItem,Room> {

	private static final RoomState DEFAULT_ROOM_STATE = RoomState.NONE;
	private static final String KEY_PREFIX_FORMAT = "room_%1$d_%2$d_";
	private static final String SUBKEY_ROOM_STATE = "room_state";
	private static final boolean DEFAULT_CHAMBER = false;
	private static final String SUBKEY_CHAMBER = "chamber";
	private static final String SUBKEY_ITEM_COUNT = "item_count";
	private static final int DEFAULT_ITEM_COUNT = 0;
	
	
	private RoomState special = DEFAULT_ROOM_STATE;
	private int x;
	private int y;
	private Map<RoomDirection,Door> doors = new HashMap<RoomDirection,Door>();
	private boolean chamber = DEFAULT_CHAMBER;

	public Room(Maze theData) {
		super(theData);
		clearData();
	}

	@Override
	protected void onLoad(SharedPreferences thePreferences) {
		//x and y are handled externally
		clearData();
		setRoomState(RoomState.valueOf(thePreferences.getString(getSubKey(SUBKEY_ROOM_STATE), DEFAULT_ROOM_STATE.toString())));
		setChamber(thePreferences.getBoolean(getSubKey(SUBKEY_CHAMBER), DEFAULT_CHAMBER));
		for(RoomDirection theDirection:RoomDirection.values()){
			getDoor(theDirection).load(thePreferences);
		}
		getItems().clear();
		int itemCount = thePreferences.getInt(getSubKey(SUBKEY_ITEM_COUNT), DEFAULT_ITEM_COUNT);
		while(getItemCount()<itemCount){
			RoomItem theItem = new RoomItem(this);
			addItem(theItem);
			theItem.load(thePreferences);
		}
		//TODO
	}

	@Override
	protected void onCommit(Editor theEditor) {
		//x and y are handled externally
		theEditor.putString(getSubKey(SUBKEY_ROOM_STATE), getRoomState().toString());
		for(RoomDirection theDirection:RoomDirection.values()){
			getDoor(theDirection).commit(theEditor);
		}
		theEditor.putInt(getSubKey(SUBKEY_ITEM_COUNT), getItemCount());
		for(RoomItem theItem:getItems()){
			theItem.commit(theEditor);
		}
		//TODO
	}

	public String getKeyPrefix() {
		return String.format(KEY_PREFIX_FORMAT,getX(),getY());
	}

	private String getSubKey(String theSubKey){
		return getKeyPrefix()+theSubKey;
	}

	@Override
	public Context getContext() {
		return getData().getContext();
	}

	public void setX(int theX) {
		x = theX;
	}
	
	public int getX(){
		return x;
	}

	public void setY(int theY) {
		y = theY;
	}
	
	public int getY(){
		return y;
	}
	
	public Door getDoor(RoomDirection theDirection){
		return getDoors().get(theDirection);
	}
	
	public Room getNeighbor(RoomDirection theDirection){
		return getData().getRoom(theDirection.nextColumn(getX(), getY()), theDirection.nextRow(getX(), getY()));
	}
	
	private void setDoor(RoomDirection theDirection, Door theDoor){
		getDoors().put(theDirection, theDoor);
	}
	
	public RoomDirection getDoorDirection(Door theDoor){
		for(RoomDirection theDirection: RoomDirection.values()){
			if(getDoor(theDirection).equals(theDoor)){
				return theDirection;
			}
		}
		return null;
	}

	private Map<RoomDirection,Door> getDoors() {
		return doors;
	}

	public void clearData() {
		setRoomState(DEFAULT_ROOM_STATE);
		clearDoors();
	}

	private void clearDoors() {
		for(RoomDirection theDirection: RoomDirection.values()){
			setDoor(theDirection,new Door(this));
		}
	}

	public RoomState getRoomState() {
		return special;
	}

	public void setRoomState(RoomState special) {
		this.special = special;
	}
	
	public int getPassableCount(){
		int theResult = 0;
		for(RoomDirection theDirection: RoomDirection.values()){
			Door theDoor = getDoor(theDirection);
			if(theDoor.getDoorState().isPassable()){
				theResult++;
			}
		}
		return theResult;
	}

	public void setChamber(boolean theChamber) {
		chamber = theChamber;
	}
	
	public boolean getChamber(){
		return chamber;
	}

	public RoomItem getRoomItem(int itemIndex) {
		return getItems().get(itemIndex);
	}
	
	public int getVisibleItemCount(){
		int theResult = 0;
		Iterator<RoomItem> iterator = getItems().iterator();
		while(iterator.hasNext()){
			RoomItem theItem = iterator.next();
			if(!theItem.isHidden()){
				theResult++;
			}
		}
		return theResult;
	}

}
